﻿using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Gxu.Models;
using NewLife.Log;
using NewLife.Web;
using XCode;
using XCode.Configuration;
using XCode.DataAccessLayer;

namespace Easy.Admin.Controllers
{
    /// <summary>
    /// 基类
    /// </summary>
    //[ManagerAuthorizationFilter]
    //[ExceptionFilter]
    //[ActionResultFilter(typeof(BaseController), "CheckViewFile")]
    public abstract class BaseController : Controller
    {
        /// <summary>
        /// 当前管理员
        /// </summary>
        public SysUsers curManager => 
            new SysUsers();
            //UserLogin.CurrUserData;

        //private List<EntityBase> _entitites = >
        //{
            
        //};

        #region 生成视图

        public static void CheckViewFile(ResultExecutingContext filterContext)
        {
            ViewResult viewResult;
            var isViewAction = (viewResult = filterContext.Result as ViewResult) != null;
            if (!isViewAction) return;
            //TODO 这里未判断是视图全路径还是视图文件名
            var viewName = filterContext.RouteData.Values["action"];
            var viewFilePath = "Views/" + filterContext.RouteData.Values["controller"];
            viewFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, viewFilePath);
            if (!Directory.Exists(viewFilePath))
            {
                Directory.CreateDirectory(viewFilePath);
            }

            if (!string.IsNullOrWhiteSpace(viewResult.ViewName))
            {
                viewName = ((ViewResult)filterContext.Result)?.ViewName;
            }

            var viewFileName = viewFilePath + "/" + viewName + ".cshtml";
            if (!System.IO.File.Exists(viewFileName))
            {
                var tableName = filterContext.RouteData.Values["controller"].ToString().Replace("Manager", "");
                CreateViewFile(viewFileName, tableName, viewName?.ToString());
            }

        }

        static void CreateViewFile(string fileName, string tableName, string viewName)
        {
            var Tables = DAL.Create("Conn").Tables;
            Func<IDataTable, string, bool> findFunc = (f, n) => f.TableName.Substring(f.TableName.IndexOf('_') + 1) == n.Substring(n.IndexOf('_') + 1);


            var Table = Tables.Find(f => findFunc(f, tableName));

            if (Table == null) return;

            #region 生成Index

            var content = "";
            if (viewName.ToLower().Contains("index") || viewName.ToLower().Contains("list"))
            {
                content += ("@{\r\n ViewBag.Title = \"");

                content += (Table.DisplayName);
                content += @"列表"";
 Layout = ""~/Views/Shared/_IndexLayout.cshtml"";
}
@section head{
}
<div class=""wrapper wrapper-content animated fadeInRight"">
    <div class=""col-sm-12"">
        <div>
            <form class=""form-inline"" id=""searchForm"" role=""form"">
                <div class=""form-group"">
                </div>
            </form>
        </div>
        <div class=""btn-group hidden-xs"" id=""exampleTableEventsToolbar"" role=""group"">
            <button id=""add"" type=""button"" class=""btn btn-outline btn-default"">
                <i class=""glyphicon glyphicon-plus"" aria-hidden=""true""></i>
            </button>
        </div>
        <table id=""exampleTableEvents"" data-height=""100%"" data-mobile-responsive=""true""></table>
    </div>
</div>
@section script
{
    <!--表格参数-->
    <script>

        tableRender.addArea = ['1000px', '100%'];//新增页宽高设置
        tableRender.editArea = ['1000px', '100%'];//编辑页宽高设置
        tableRender.options['url'] =  '@(Url.Action(""GetTableDataList"",new{tableName=""";
                content += tableName;
                content += @"""}))';
        tableRender.options['columns'] =  [
            {
                title: '操作',
                field: 'id',
                align: 'center', width: ""12%"",
                formatter: function (value, row, index) {
                    var e = '<a href=""javascript:void(0);"" title=""编辑此记录"" onclick=""tableRender.edit(\'' + row.ID + '\')"">编辑</a> ';
                    var d = '<a href=""javascript:void(0);"" title=""删除此记录"" onclick=""tableRender.del(\'' + row.ID + '\')"">删除</a> ';
                    return e + d;
                }
            }
            ";
                foreach (IDataColumn Field in Table.Columns)
                {
                    String pname = Field.Name;
                    if (Field.PrimaryKey || pname.Equals("Password", StringComparison.OrdinalIgnoreCase) || pname.Equals("Pass", StringComparison.OrdinalIgnoreCase) || Field.Length >
                        500) continue;
                    TypeCode code = Type.GetTypeCode(Field.DataType);
                    var temp = "";
                    temp += ("title: \'");
                    temp += (Field.DisplayName.TrimEnd("id"));
                    temp += ("\', field: \'");
                    temp += (Field.Name);
                    temp += ("\', align: \'center\'");
                    switch (code)
                    {
                        case TypeCode.String:
                            if (Field.Length > 50 || Field.Length < 0)
                            {
                                continue;
                            }
                            else
                            {
                                content += ", { " + temp + "}";
                                break;
                            }
                        case TypeCode.Int32:
                        case TypeCode.Double:
                        case TypeCode.Decimal:
                            content += ", { " + temp + "}";
                            break;
                        case TypeCode.DateTime:
                            content += (", {\r\n                        ");
                            content += temp;
                            content += ", formatter: function (value, row, index) {\r\n                  " +
                                        "      return ChangeDateFormat(value);\r\n                    }\r\n                }";
                            break;
                        case TypeCode.Boolean:
                            content += (", {\r\n                        ");
                            content += temp;
                            content += ", formatter: function (value, row, index) {\r\n                  " +
                                       "      return value?\"是\":\"否\";\r\n                    }\r\n                }";
                            break;
                    }
                    content += @"
            ";
                }
                content += @"
        ];
    </script>";
                content += @"
    <!--渲染搜索条件-->
    <script>
        renderForm([@*将表单页的设置想复制过来即可*@], '#searchForm', function (form, input, item) {
            var label = '<label>' + item.displayName + '</label>';
            input = input.replace('{replace}', 'class=""form-control""');//将占位符替换为自定义内容
            var content = '&nbsp;&nbsp;<div class=""form-group"">' + label +'&nbsp;'+ input + '</div>';
            form.append(content);
        })
    </script>
}";
            }
            #endregion

            #region 生成Edit

            else
            {
                viewName = "edit";//到这里的大概都是表单页，为了生成配置项
                var viewTemplateFilePath = ("Views/ViewTemplate/" + viewName + ".cshtml").GetFullPath();

                if (System.IO.File.Exists(viewTemplateFilePath))
                {
                    content = System.IO.File.ReadAllText(viewTemplateFilePath);
                }
            }


            #endregion
            System.IO.File.WriteAllText(fileName, content, Encoding.UTF8);

            //System.IO.File.AppendAllText(fileName, content, Encoding.UTF8);
        }
        #endregion
        //[Route("{controller}/Get{tableName}DataList")]
        /// <summary>
        /// 获取表格数据
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="keyword"></param>
        /// <param name="page"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        [Route("*/GetTableDataList")]
        public JsonResult GetTableDataList(string tableName, string keyword, Pager page, string[] name, string[] value)
        {
            try
            {
                //查找表名所在数据访问层
                var dals = DAL.ConnStrs.Select(s => DAL.Create(s.Key));
                IDataTable table = null;
                var dal = dals.First(f => f.Tables.Find(t =>
                {
                    var isMatch = t.Name.Substring(t.Name.IndexOf('_') + 1) == tableName;
                    if(!isMatch) isMatch = t.Name.Substring(t.Name.IndexOf('_') + 1) == tableName.Substring(tableName.IndexOf('_') + 1);
                    if (isMatch) table = t;
                    return isMatch;
                }) != null);
                if (dal == null || table == null) return Json("");

                


                var factory = dal.CreateOperate(table.TableName);
                var orderClause = "";
                if (!page.Sort.IsNullOrWhiteSpace()) orderClause = page.Sort + " " + page.Desc;
                var whereClause = SearchWhere(keyword, tableName, name, value);
                
                var c = factory.FindAll(whereClause,null,null,0,0);
                long count = factory.FindCount(whereClause,null,null,0,0);

                //实体类型
                var entityType = (EntityTypeHt[tableName] as Type);
                if (entityType == null) return Json("");

                var action = entityType.BaseType?.GetMethods()[25];//TODO 版本升级之后可能就不是25了，得换个方式
                var list = action?.Invoke(null, new object[] { whereClause, orderClause, null, 0, 0});

                var result = new Hashtable
                {
                    ["pager.totalRows"] = count,
                    ["rows"] = list
                };
                return Json(result, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                XTrace.WriteLine(e.Message+"\r\n"+e.StackTrace);
                return Json("");
            }

        }
        /// <summary>
        /// 构建搜索条件
        /// </summary>
        /// <param name="key"></param>
        /// <param name="tableName"></param>
        /// <param name="names"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public string SearchWhere(string key, string tableName, string[] names, string[] values)
        {
            WhereExpression exp = null;
            var tableItem = (TableItemHt[tableName] ?? (TableItemHt[tableName] = TableItem.Create((EntityTypeHt[tableName] as Type) ?? typeof(int)))) as TableItem;

            if (tableItem == null) return (WhereExpression)null;
            var fields = tableItem.AllFields.Where(w => w.Field != null).ToArray();
            if (key != null)
                exp &= Entity<Dictionary>.SearchWhereByKey(key, fields);
            if (names == null || names.Length <= 0 || names.Length != values.Length) return exp;
            for (var i = 0; i < names.Length; i++)
            {
                if (values[i]== "undefined"|| values[i].IsNullOrWhiteSpace()) continue;
                var fi = tableItem.FindByName(names[i]);
                if ((object)fi == null) continue;
                exp &= fi == values[i];
            }
            return exp;
        }

        private static Hashtable _entityTypeHt;
        /// <summary>
        /// 所有实体类型
        /// </summary>
        public static Hashtable EntityTypeHt
        {
            get
            {
                if (_entityTypeHt != null) return _entityTypeHt;
                _entityTypeHt = new Hashtable();
                foreach (var type in typeof(Dictionary).Assembly.GetTypes().Where(w => w?.BaseType?.BaseType == typeof(EntityBase)))
                {
                    _entityTypeHt[type.Name] = type;
                }
                return _entityTypeHt;
            }
        }
        /// <summary>
        /// 缓存实体的字段
        /// </summary>
        public static Hashtable TableItemHt = new Hashtable();
    }


}
